package visiopuce.ideogram.input;

import java.io.IOException;
import java.util.Collection;
import java.util.LinkedList;
import java.util.TreeSet;

import visiopuce.ideogram.IdeogramMainWindow;
import visiopuce.ideogram.tree.Interval;
import visiopuce.ideogram.util.FileFormatException;

public class ParamTextReaderModel extends AbstractCopyNumberDataModel {
	private TreeSet<CopyNumberRecord> data;
	CopyNumberRecord[] cache;

	private boolean valid; // valid state
	private String fileName; // *.txt file name

	public ParamTextReaderModel() {
		super();

		data = new TreeSet<CopyNumberRecord>();
		cache = null;
		valid = false;
	}

	/**
	 * Read "Tabbed Text File" format.
	 * 
	 * @param the
	 *            *txt file
	 */
	public void load() throws IOException, FileFormatException {
		clear();
		readElements();
		fileName = "CNV";
		fireChangeEvent();
	}

	public void clear() {
		data.clear();
		valid = false;
		fileName = "";
	}

	public boolean isValid() {
		return valid;
	}

	private void updateCache() {
		if (data == null) {
			cache = null;
			return;
		}
		if ((cache == null) || (cache.length != data.size())) {
			cache = new CopyNumberRecord[data.size()];
		}
		data.toArray(cache);
	}

	public void validate() {
		if (!valid) {
			updateCache();
			valid = true;
		}

	}

	/**
	 * Loads a marker collection from a stream. The input stream must be a tab
	 * delimited ASCII format with the following columns CHROMOSOME 1..22,X,Y
	 * START_BP integer > 0 STOP_BP integer > 0 NAME string VALUE integer
	 * 
	 * @throws IOException
	 * @throws FileFormatException
	 */
	public void readElements() throws IOException, FileFormatException {
		invalidate();
		if (IdeogramMainWindow.causal  != null && !IdeogramMainWindow.causal.equals("")) {
			String[] lignes = IdeogramMainWindow.causal.split(";;");
			for (int i = 0; i < lignes.length; i++) {
				String ligne = lignes[i];
				String[] donnees = ligne.split("::");

				CopyNumberRecord record = new CopyNumberRecord();

				if (donnees[0].equals("X"))
					record.locus.chromosome = 23;
				else if (donnees[0].equals("Y"))
					record.locus.chromosome = 24;
				else
					record.locus.chromosome = Byte.parseByte(donnees[0]);

				record.locus.interval = new Interval(
						Long.parseLong(donnees[1]), Long.parseLong(donnees[2]));
				Integer type = Integer.parseInt(donnees[5]);
				String sexe = donnees[8];
				if (!donnees[0].equals("Y") && !donnees[0].equals("X")) {
					switch (type) {
					case 0:
						record.copy_number = 0;
						break;
					case 1:
						record.copy_number = 1;
						break;
					case 2:
						record.copy_number = 2;
						break;
					case 3:
						record.copy_number = 3;
						break;
					case 4:
						record.copy_number = 4;
						break;
					default:
						record.copy_number = 2;
						break;
					}
				} else {
					if (sexe.equals("M")) {
						switch (type) {
						case 0:
							record.copy_number = 1;
							break;
						case 1:
							record.copy_number = 2;
							break;
						case 2:
							record.copy_number = 3;
							break;
						case 3:
							record.copy_number = 4;
							break;
						default:
							record.copy_number = 2;
							break;
						}

					} else if (sexe.equals("F")) {
						if (donnees[0].equals("Y")) {
							switch (type) {
							case 0:
								record.copy_number = 1;
								break;
							default:
								record.copy_number = 2;
								break;
							}
						} else if (donnees[0].equals("X")) {
							switch (type) {
							case 0:
								record.copy_number = 0;
								break;
							case 1:
								record.copy_number = 1;
								break;
							case 2:
								record.copy_number = 2;
								break;
							case 3:
								record.copy_number = 3;
								break;
							case 4:
								record.copy_number = 4;
								break;
							default:
								record.copy_number = 2;
								break;
							}
						}
					}
				}
			
				
				
				record.copy_number = (int) Double.parseDouble(donnees[5]);
				
				
				record.info = donnees[3]+"("+donnees[4]+")";
				
				record.link = donnees[6];
				data.add(record);
			}
		}

	}

	private void invalidate() {
		valid = false;

	}

	public LinkedList<String> getFileName() {
		LinkedList<String> l = new LinkedList<String>();
		l.add(fileName);
		return l;
	}

	public CopyNumberRecord get(int idx) {
		validate();
		if (cache == null || data == null)
			throw new IllegalStateException("no records available");

		if (idx < 0 || idx >= cache.length)
			throw new IndexOutOfBoundsException("Tried to access index " + idx
					+ "in an array with size" + cache.length);
		return cache[idx];
	}

	public String getMarkerName(int idx) {
		return get(idx).info;
	}

	public byte getChromosome(int idx) {
		return get(idx).locus.chromosome;
	}

	public Interval getInterval(int idx) {
		return get(idx).locus.interval;
	}

	public int size() {
		return data.size();
	}

	public double getConfidence(int idx) {
		return 0;
	}

	public int getCopyNumber(int idx) {
		return get(idx).copy_number;
	}

	public String getMarkerInfo(int i) {
		return getMarkerName(i);
	}

	public byte getChromosomeIndex(int idx) {
		return get(idx).locus.chromosome;
	}

	public Collection<CopyNumberRecord> toCollection() {
		return data;
	}

	public LinkedList<String> getHeader() {
		LinkedList<String> l = new LinkedList<String>();
		l.add("TabbedTextReader doesn't contain any header");
		return l;
	}

	public LinkedList<String> getChipType() {
		LinkedList<String> l = new LinkedList<String>();
		l.add("TabbedTextReader doesn't contain any ChipType");
		return l;
	}

}
